package controller

import (
	"context"
	"crypto/md5"
	"fmt"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/goai"
	"wh-1-backend/api/v1"
	"wh-1-backend/internal/dao"
	"wh-1-backend/internal/model/do"
	"wh-1-backend/internal/model/entity"
)

var (
	Hello = cHello{}
)

type cHello struct{}

func (c *cHello) Hello(ctx context.Context, req *v1.HelloReq) (res *v1.HelloRes, err error) {
	//g.RequestFromCtx(ctx).Response.Writeln("Hello World!")
	g.Dump(g.RequestFromCtx(ctx).Router)
	var tags = make(map[string]entity.AdminPermission)

	for uri, path := range g.RequestFromCtx(ctx).Server.GetOpenApi().Paths {
		if get := path.Get; get != nil {
			err = test(ctx, get, "GET", uri, tags)
		}
		if post := path.Post; post != nil {
			err = test(ctx, post, "POST", uri, tags)
		}
		if put := path.Put; put != nil {
			err = test(ctx, put, "PUT", uri, tags)
		}
		if del := path.Delete; del != nil {
			err = test(ctx, del, "DELETE", uri, tags)
		}
	}
	return
}

func test(ctx context.Context, opt *goai.Operation, method string, uri string, tags map[string]entity.AdminPermission) (err error) {
	var (
		tag             string
		md5Tag          string
		adminPermission *entity.AdminPermission
		md5Lab          string
		permission      *entity.AdminPermission
	)
	if len(opt.Tags) != 0 {
		tag = opt.Tags[0]
	}
	md5Tag = fmt.Sprintf("%x", md5.Sum([]byte(tag)))

	if t, ok := tags[md5Tag]; ok {
		adminPermission = &t
	} else {
		err = dao.AdminPermission.Ctx(ctx).Where(dao.AdminPermission.Columns().Slug, md5Tag).Scan(&adminPermission)
		if err != nil {
			return
		}
		if adminPermission == nil {
			id, err1 := dao.AdminPermission.Ctx(ctx).InsertAndGetId(do.AdminPermission{
				Label: tag,
				Slug:  md5Tag,
			})
			if err1 != nil {
				return err1
			}
			adminPermission = &entity.AdminPermission{Id: uint(id)}
		}
		tags[md5Tag] = *adminPermission
	}
	md5Lab = fmt.Sprintf("%x", md5.Sum([]byte(method+uri)))
	err = dao.AdminPermission.Ctx(ctx).Where(dao.AdminPermission.Columns().Slug, md5Lab).Scan(permission)
	if err != nil {
		return
	}
	if permission == nil {
		_, err = dao.AdminPermission.Ctx(ctx).Insert(do.AdminPermission{
			Pid:    adminPermission.Id,
			Label:  opt.Summary,
			Uri:    uri,
			Method: method,
			Slug:   md5Lab,
			Type:   1,
		})
	} else {
		_, err = dao.AdminPermission.Ctx(ctx).Where(dao.AdminPermission.Columns().Slug, md5Lab).Update(do.AdminPermission{
			Id:     permission.Id,
			Label:  opt.Summary,
			Uri:    uri,
			Method: method,
		})
	}
	if err != nil {
		return
	}
	return
}
